/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package practica1compi1;
import java.io.*;
import java.util.*;
/**
 *
 * @author Otto
 */
public class subConjuntos {
    String matriz[][]=new String [2][];
    String nuevaMatriz[][]= new String[50][50];
    String MatrizEstadosNuevos[][]=new String[2][50];
    int _NuevoEstado = 65;
    int _UltimoNuevoEstadoUsado=_NuevoEstado;
    int Contador=0;
    List<String> ePendiente=new ArrayList();
     static final int Total=50; 
     int _Alfabeto=0;
     
     List<String> eAceptacion=new ArrayList();
     
    public void Inicilizar(String m[][]){
        matriz=m;
        m[0][0]="ESTADO";
        for (int i=1;i<Total;i++){
            if (m[i][0].equals("ε"))
                break;
            nuevaMatriz[i][0] = m[i][0];
            _Alfabeto++;
        }
        
        AgregarEstado(matriz[0][1]+",",false);
        
        for (int i=1;i<Total;i++){
             if (matriz[0][i]==null)
                break;
             boolean eAcepta=false; 
             
            for (int j=1;j<_Alfabeto+2;j++){
               if (matriz[j][i]!=null){
                   eAcepta=true;
                   break;
               }
               
                
            }
            if (!eAcepta)
                eAceptacion.add(matriz[0][i]);
        }
        while(ePendiente.size()>0){
            String ns =ObtenerSiguienteNuevoEstado();
            for (int i =0;i<Total;i++){
                if (MatrizEstadosNuevos[0][i].equals(ns)){
                    CerraduraS(MatrizEstadosNuevos[1][i],MatrizEstadosNuevos[0][i]);
                    break;
                }
            }
        } 
        int x=0;
        x++;
    }
    
    public void Calcular(String eInicial){
    };
    
    
 
    
    private void AgregarEstado(String estadosAFN,boolean eAceptacion){
        boolean existe =false;
        //eliminar repetidos y ordenar
        estadosAFN=EliminarYOrdenar(estadosAFN);
        //buscar si ya existe en los estados creados
        String Insercion[]=estadosAFN.split(",");
        for (int i=0;i<_NuevoEstado-65;i++){  
            existe =false;
            for (int j=0;j<Insercion.length;j++){
                if (MatrizEstadosNuevos[1][i].contains(Insercion[j])){
                    existe =true;
                }
                else{
                     existe =false;
                     break;
                }
            }
            if(existe)
                break;
        }
        
        if (!existe){
            MatrizEstadosNuevos[0][_NuevoEstado-65]=(char)_NuevoEstado+"";
            MatrizEstadosNuevos[1][_NuevoEstado-65]=estadosAFN;

            if (eAceptacion)
                nuevaMatriz[0][_NuevoEstado-64]=(char)_NuevoEstado+"*";
            else
                nuevaMatriz[0][_NuevoEstado-64]=(char)_NuevoEstado+"";

            ePendiente.add((char)_NuevoEstado+"");
            _NuevoEstado++;                
        }
    }
    
    private String EliminarYOrdenar(String str){
        String Result="";
        String a1[] = str.split(",");
        
        for (int i=0;i<a1.length;i++){
            if (Result.contains(a1[i])){
                
            }
            else{
                Result=Result+a1[i]+",";
            }
        }
        
        return Result;
    }
    
    private boolean Acepta(String s){ 
        for (int i=0;i<eAceptacion.size();i++){
            if (eAceptacion.get(i).equals(s))
                return true;
        }
        return false;
    }
    private String CerraduraS(String Estado,String Nombre)    {
        String lStrEstado="";
        String Transicion="";
        String estadosSubConjunto[] = Estado.split(",");
        String nuevoEstado="";
        boolean eAceptacion=false;
       
        for (int j=1;j<_Alfabeto+1;j++){
            nuevoEstado="";
            for(int k =0;k<estadosSubConjunto.length;k++){
                
//                if (Acepta(estadosSubConjunto[k]))
//                    nuevoEstado=nuevoEstado+estadosSubConjunto[k]+",";
//                else{ 
                    for(int i =1;i<Total;i++){
                        if (matriz[0][i]!=null){
                            if (matriz[0][i].equals(estadosSubConjunto[k])){
                                if (matriz[j][i]!=null){  
                                            nuevoEstado=nuevoEstado+matriz[j][i];
                                }                    
                            }             
                        }
                        else{
                            break;
                        }
                    }
                
//                }
                   
                }
                if (nuevoEstado.length()>0){
                    Mov(Nombre,matriz[j][0],eAceptacion,nuevoEstado); 
                    nuevoEstado =nuevoEstado+RevisaTranicionesEpsilon(nuevoEstado);}
                if (nuevoEstado.length()>0)
                    AgregarEstado(nuevoEstado,eAceptacion);
            }
     
//        for(int k =0;k<estadosSubConjunto.length;k++){
//
//            for(int i =1;i<Total;i++){
//                if (matriz[0][i]!=null)
//                {
//                    if (matriz[0][i].equals(estadosSubConjunto[k])){
//
//                        for (int j=1;j<_Alfabeto+1;j++){
//                                if (matriz[j][i]!=null){
//                                    lStrEstado=matriz[j][i];
//                                    Transicion=matriz[j][0];
//                                    Mov(Nombre,Transicion,eAceptacion,lStrEstado); 
//                                    nuevoEstado=nuevoEstado+lStrEstado;
//                                    break;
//                                }
//                                if(j==Total-1){
//                                    lStrEstado=matriz[j][i]; 
//                                    nuevoEstado=nuevoEstado+lStrEstado;
//                                    eAceptacion=true;
//                                }
//                            }   
//                    } 
//                }
//                else
//                    break;
//            } 
//        } 
//        
//        nuevoEstado =nuevoEstado+RevisaTranicionesEpsilon(nuevoEstado);
//        if (nuevoEstado.length()>0)
//            AgregarEstado(nuevoEstado,eAceptacion);
        
        return lStrEstado;
    }
    
    private String RevisaTranicionesEpsilon(String est2){
        String lStrResult="";
        String st[] = est2.split(",");
        
        for(int i = 0 ; i<st.length;i++){
             for(int j =1;j<Total;j++){
                 if (matriz[0][j]!=null){
                    if (matriz[0][j].equals(st[i])){
                        if (matriz[_Alfabeto+1][j]!=null){
                            lStrResult=lStrResult+matriz[_Alfabeto+1][j];
                        }
                    }
                 }
                 else
                     break;
             }
        }
        if (lStrResult!="")
            lStrResult=lStrResult+RevisaTranicionesEpsilon(lStrResult);
        
        return lStrResult;
    }
    
    private String[] EliminarRepetidos(String est2){ 
        String st[] = est2.split(",");
        
        est2.replaceFirst("","");
        
        return st;
    } 
    private void  Mov(String Estado,String Transicion,boolean eAceptacion,String es){
        for(int i=1;i<_NuevoEstado-64;i++){
              if (nuevaMatriz[0][i].equals(Estado))
              {
                  for (int j=1;j<=_Alfabeto;j++)
                  {
                      if (nuevaMatriz[j][0].equals(Transicion)){
                          nuevaMatriz[j][i]=es;
                          break;
                      }
                  }
              }
        }   
    }
    
    
    private String ObtenerSiguienteNuevoEstado(){
         String result;
        if (ePendiente.size()>0){
              result=ePendiente.get(0);
              ePendiente.remove(0);
        }
        else
            result=null;
        
        return result;
    }
}
